package route

import (
	"database/sql"
	mysqlMod "route/mysql"
	"runtime"
	"sync"
)

// StmtMap database/sql.stmt 的集合封装
type StmtMap map[string]*StmtSubMap

type StmtSubMap struct {
	stmt map[string][]*sql.Stmt
	sync.RWMutex
}

func (stmt StmtMap) GetStmt(key1, key2 string, index int) *sql.Stmt {
	inst := stmt[key1]
	inst.Lock()
	defer inst.RLock()
	return inst.stmt[key2][index]
}

var (
	StmtPrepare = map[string]map[string][]string{
		"admin_user": map[string][]string{
			"select": {
				"SELECT u.id, u.password, u.salt FROM admin_user u" +
					" INNER JOIN (SELECT p.id FROM person p WHERE num_job=?) p ON p.id = u.id_person ",
			},
		},
		"document": map[string][]string{
			"select": {
				"SELECT path, simple_path FROM process_drawing",
				"SELECT id FROM process_drawing WHERE path=?",
			},
			"insert": {},
			"delete": {
				"DELETE FROM admin_log ORDER BY id DESC LIMIT ?",
			},
		},
		"process_drawing": map[string][]string{
			"insert": {
				"INSERT INTO process_drawing " +
					" (id_user_create, id_user_modify, path, simple_path, date_create, date_modify)" +
					" VALUES (?, ?, ?, ?, ?, ?)",
			},
		},
	}
)

// NewStmt 从 mysql-mode 更新
func NewStmt(prepare map[string]map[string][]string) (StmtMap, error) {
	stmts := make(map[string]*StmtSubMap)
	for k, v := range prepare {
		stmts[k] = &StmtSubMap{}
		for sk, sv := range v {
			stmtList := []*sql.Stmt{}
			for _, ssv := range sv {
				stmt, err := mysqlMod.Prepare(ssv)
				if err != nil {
					return nil, err
				}
				stmtList = append(stmtList, stmt)
			}
			stmts[k].stmt[sk] = stmtList
		}
	}
	runtime.SetFinalizer(&stmts, stmtFinalizer)
	return StmtMap(stmts), nil
}

// stmtFinalizer 析构函数
// 析构需要关闭 stmt
func stmtFinalizer(stmt *map[string]map[string][]*sql.Stmt) {
	for k, v := range *stmt {
		for _, sv := range v {
			for _, ssv := range sv {
				ssv.Close()
			}
		}
		delete(*stmt, k)
	}
}
